package com.educhains.web.handler;

import com.educhains.module.chat.service.MessageService;
import com.educhains.module.chat.vo.Message;
import com.educhains.module.user.service.UserService;
import com.educhains.web.util.JsonUtils;
import com.educhains.web.util.StringUtils;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.*;

import java.io.IOException;
import java.util.*;

/**
 * @author YuRun
 * @since 2017年11月3日
 */
@Component
public class EduchainsWebSocketHandler implements WebSocketHandler {

    private static final Logger log = Logger.getLogger(EduchainsWebSocketHandler.class);

    private static final String AI_ID = "3651f74104e846e99f33eb36f5ddf43e";

    @Autowired
    private MessageService messageService = null;

    @Autowired
    private UserService userService = null;

    private Message msg;

    private static final Map<String, WebSocketSession> userSocketSessionMap;

    static {
        userSocketSessionMap = new HashMap<String, WebSocketSession>();
    }

    /**
     * Connection be all set
     *
     * @param session
     * @throws Exception
     */
    public void afterConnectionEstablished(WebSocketSession session)
            throws Exception {
        log.info("connect websocket success......");

        String userId = (String) session.getAttributes().get("userId");
        if (userSocketSessionMap.get(userId) == null) {
            userSocketSessionMap.put(userId, session);
        }
    }

    /**
     * Handle talk
     *
     * @param session
     * @param message
     * @throws Exception
     */
    public void handleMessage(WebSocketSession session,
                              WebSocketMessage<?> message) throws Exception {

        if (message.getPayloadLength() == 0) return;

        log.info("handleMessage......." + message.getPayload() + "......");


        //Message msg = new Gson().fromJson(message.getPayload().toString(), Message.class);
        msg = new Gson().fromJson(message.getPayload().toString(), Message.class);

        Date now = new Date();
        msg.setMessageTime(now);
        System.out.println(JsonUtils.toJSONString(userService.selectUserById(msg.getMessageToId())));
        //msg.setToUserPhoto(userService.selectUserById(msg.getMessageToId()).getUserPhoto());
        messageService.addMessage(msg);

        sendMessageToUser(msg.getMessageToId(), new TextMessage(new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create().toJson(msg)));
        if (msg.getMessageToId().compareTo(AI_ID) == 0) {
            new Thread(new Runnable() {
                public void run() {
                    String text = messageService.getAIChat(msg.getMessageFromId(), msg.getMessageText());
                    Message messageFromAI = new Message();
                    Calendar calendar = Calendar.getInstance();
                    calendar.setTime(new Date());
                    calendar.add(Calendar.SECOND, 1);
                    messageFromAI.setMessageTime(calendar.getTime());

                    messageFromAI.setMessageFromId(AI_ID);
                    messageFromAI.setMessageToId(msg.getMessageFromId());
                    messageFromAI.setMessageText(text);
                    messageFromAI.setFromUserPhoto(userService.selectUserById(msg.getMessageToId()).getUserPhoto());
                    messageService.addMessage(messageFromAI);
                    try {
                        sendMessageToUser(msg.getMessageFromId(), new TextMessage(new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create().toJson(messageFromAI)));
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        }
    }

    /**
     * Handle transport error
     *
     * @param session
     * @param exception
     * @throws Exception
     */
    public void handleTransportError(WebSocketSession session,
                                     Throwable exception) throws Exception {
        // TODO Auto-generated method stub

    }

    /**
     * Connection closed
     *
     * @param session
     * @param closeStatus
     * @throws Exception
     */
    public void afterConnectionClosed(WebSocketSession session,
                                      CloseStatus closeStatus) throws Exception {
        log.info("connect websocket closed.......");
        Iterator<Map.Entry<String, WebSocketSession>> iterator = userSocketSessionMap.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, WebSocketSession> entry = iterator.next();
            if (entry.getValue().getAttributes().get("userId") == session.getAttributes().get("userId")) {
                System.out.println("WebSocket in staticMap:" + session.getAttributes().get("userId") + " removed");
                userSocketSessionMap.remove(session.getAttributes().get("userId"));
            }
        }
    }

    public boolean supportsPartialMessages() {
        // TODO Auto-generated method stub
        return false;
    }

    public void sendMessageToUser(String toId, TextMessage message)
            throws IOException {
        WebSocketSession session = userSocketSessionMap.get(toId);
        if (session != null && session.isOpen()) {
            session.sendMessage(message);
        }
    }
}
